package jinyilw.swing.rlaf.ui;

import jinyilw.swing.ComponentTools;
import jinyilw.swing.FontTools;
import jinyilw.swing.graphics.GraphicsTools;
import jinyilw.swing.rlaf.theme.RThemeColor;

import javax.swing.Icon;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;

/**
 * @author Jinyi
 */
public class RInternalFrameTitlePane extends BasicInternalFrameTitlePane
{
	private static final long serialVersionUID = -7654069757850260139L;
	private static final AlphaComposite alphaComposite = ComponentTools.alphaComposite;
	private static final int CLOSE = 1, MAX = 2, MIN = 3, ICON = 4;

	private static final Icon iiconIcon = new Symbol(ICON);
	private static final Icon icloseIcon = new Symbol(CLOSE);
	private static final Icon acloseIcon = new Symbol(CLOSE, Color.red);
	private static final Icon imaxIcon = new Symbol(MAX);
	private static final Icon iminIcon = new Symbol(MIN);

	public RInternalFrameTitlePane(JInternalFrame f)
	{
		super(f);
	}

	@Override
	public void paintComponent(Graphics g)
	{
		paintTitleBackground(g);

		if (frame.getTitle() == null)
			return;
		boolean isSelected = frame.isSelected();
		Font f = getFont();
		g.setFont(f);
		if (isSelected)
			g.setColor(RThemeColor.colorSet.textColor);
		else
			g.setColor(RThemeColor.colorSet.unSelectFTColor);

		FontMetrics fm = g.getFontMetrics(f);
		int baseline = (getHeight() + fm.getAscent() - fm.getLeading()
				- fm.getDescent()) / 2;

		int titleX;
		Rectangle r = new Rectangle(0, 0, 0, 0);
		if (frame.isIconifiable())
			r = iconButton.getBounds();
		else if (frame.isMaximizable())
			r = maxButton.getBounds();
		else if (frame.isClosable())
			r = closeButton.getBounds();
		int titleW;

		String title = frame.getTitle();
		if (ComponentTools.isLeftToRight(frame))
		{
			if (r.x == 0)
				r.x = frame.getWidth() - frame.getInsets().right;
			titleX = menuBar.getX() + menuBar.getWidth() + 2;
			titleW = r.x - titleX - 3;
			title = getTitle(frame.getTitle(), fm, titleW);
		} else
		{
			titleX = menuBar.getX() - 2 - fm.stringWidth(title);
		}
		GraphicsTools.drawSmoothString(g, title, titleX, baseline);
	}

	@Override
	protected void paintTitleBackground(Graphics g)
	{
		Graphics2D g2d = (Graphics2D) g;
		Composite composite = g2d.getComposite();
		boolean isSelected = frame.isSelected();
		if (isSelected)
		{
			closeButton.setIcon(acloseIcon);
			g.setColor(RThemeColor.colorSet.transBGColor.brighter());
		} else
		{
			closeButton.setIcon(icloseIcon);
			g.setColor(RThemeColor.colorSet.transBGColor);
		}
		g.fillRect(0, 0, getWidth(), getHeight());
		g2d.setComposite(alphaComposite.derive(0.6f));
		g.fillRect(0, 0, getWidth(), getHeight());
		g2d.setComposite(composite);
	}

	@Override
	protected void installDefaults()
	{
		setFont(FontTools.defaultFont);
	}

	@Override
	protected void createButtons()
	{
		iconButton = new IconButton();
		iconButton.addActionListener(iconifyAction);
		maxButton = new IconButton();
		maxButton.addActionListener(maximizeAction);
		closeButton = new IconButton();
		closeButton.addActionListener(closeAction);
		closeButton.setIcon(icloseIcon);
		setButtonIcons();
	}

	@Override
	protected void setButtonIcons()
	{
		if (frame.isIcon())
		{
			iconButton.setIcon(iminIcon);
			maxButton.setIcon(imaxIcon);
		} else if (frame.isMaximum())
		{
			iconButton.setIcon(iiconIcon);
			maxButton.setIcon(iminIcon);
		} else
		{
			iconButton.setIcon(iiconIcon);
			maxButton.setIcon(imaxIcon);
		}
	}

	@Override
	protected void assembleSystemMenu()
	{
		menuBar = createSystemMenuBar();
		// windowMenu = createSystemMenu();
		// menuBar.add(windowMenu);
		// addSystemMenuItems(windowMenu);
		// enableActions();
	}

	@Override
	protected void addSystemMenuItems(JMenu systemMenu)
	{

	}

	@Override
	protected LayoutManager createLayout()
	{
		return new TitlePaneLayout();
	}

	class TitlePaneLayout implements LayoutManager
	{
		@Override
		public void addLayoutComponent(String name, Component c)
		{
		}

		@Override
		public void removeLayoutComponent(Component c)
		{
		}

		@Override
		public Dimension preferredLayoutSize(Container c)
		{
			return minimumLayoutSize(c);
		}

		@Override
		public Dimension minimumLayoutSize(Container c)
		{
			int width = 22;
			if (frame.isClosable())
				width += 19;
			if (frame.isMaximizable())
				width += 19;
			if (frame.isIconifiable())
				width += 19;

			FontMetrics fm = frame.getFontMetrics(getFont());
			String frameTitle = frame.getTitle();
			int title_w = frameTitle != null ? fm.stringWidth(frameTitle) : 0;
			int title_length = frameTitle != null ? frameTitle.length() : 0;

			if (title_length > 3)
			{
				int subtitle_w = fm
						.stringWidth(frameTitle.substring(0, 3) + "...");
				width += Math.min(title_w, subtitle_w);
			} else
			{
				width += title_w;
			}

			Icon icon = frame.getFrameIcon();
			int fontHeight = fm.getHeight();
			fontHeight += 2;
			int iconHeight = 0;
			if (icon != null)
				iconHeight = Math.min(icon.getIconHeight(), 16);
			iconHeight += 2;

			int height = Math.max(fontHeight, iconHeight);
			Dimension dim = new Dimension(width, height);
			if (getBorder() != null)
			{
				Insets insets = getBorder().getBorderInsets(c);
				dim.height += insets.top + insets.bottom;
				dim.width += insets.left + insets.right;
			}
			return dim;
		}

		@Override
		public void layoutContainer(Container c)
		{
			boolean leftToRight = ComponentTools.isLeftToRight(frame);

			int w = getWidth();
			int h = getHeight();
			int x, y;

			int size = closeButton.getIcon().getIconHeight();

			Icon icon = frame.getFrameIcon();
			int iconHeight = 0;
			if (icon != null)
				iconHeight = icon.getIconHeight();

			x = (leftToRight) ? 2 : w - 16 - 2;
			menuBar.setBounds(x, (h - iconHeight) / 2, 16, 16);

			x = (leftToRight) ? w - 16 - 2 : 2;
			y = (h - size) / 2;
			if (frame.isClosable())
			{
				closeButton.setBounds(x, y, size, size);
				x += (leftToRight) ? -(size + 1) : size + 1;
			}
			if (frame.isMaximizable())
			{
				maxButton.setBounds(x, y, size, size);
				x += (leftToRight) ? -(size + 1) : size + 1;
			}
			if (frame.isIconifiable())
				iconButton.setBounds(x, y, size, size);
		}
	}

	static class IconButton extends NoFocusButton
	{
		private static final long serialVersionUID = 622497569452920990L;

		@Override
		public void updateUI()
		{
			setUI(new RoundButtonUI());
		}
	}

	static class Symbol implements Icon
	{
		private final int type;
		private Color symbolColor;

		public Symbol(int type)
		{
			this.type = type;
		}

		public Symbol(int type, Color color)
		{
			this.type = type;
			symbolColor = color;
		}

		@Override
		public int getIconHeight()
		{
			return 17;
		}

		@Override
		public int getIconWidth()
		{
			return 17;
		}

		@Override
		public void paintIcon(Component c, Graphics g, int x, int y)
		{
			x = 0;
			y = 0;
			Color color = symbolColor != null
					? symbolColor
					: RThemeColor.colorSet.textColor;
			int w = c.getWidth(), h = c.getHeight();
			switch (type)
			{
				case CLOSE:
					GraphicsTools.drawCloseSymbol(g, color, null, x, y, w, h);
					break;
				case MAX:
					GraphicsTools.drawMaxSymbol(g, color, null, x, y, w, h);
					break;
				case MIN:
					GraphicsTools.drawMinSymbol(g, color, null, x, y, w, h);
					break;
				case ICON:
					GraphicsTools.drawIconSymbol(g, color, null, x, y, w, h);
			}
		}
	}
}
